/***************************************************************************
 *   Copyright (C) 2011 by The rPem3d developers                           *
 *   elseifkk@users.sf.net                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "cpumonitor.h"
#include "palette.h"

#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <stdlib.h>

#include <qpainter.h>

//
CpuMonitor::~CpuMonitor()
{
}

//
CpuMonitor::CpuMonitor ( QWidget *parent, const char *name )
		: QLabel ( parent, name )
{
	int w;
	ncpus=0;
	maxcpus=0;
	ccalib=0;
	int const interval=700; // ms

#if defined(__FreeBSD__) && (__FreeBSD__ >= 7)
	size_t len;
	len=sizeof ( ncpus );
	if ( sysctlbyname ( "kern.smp.cpus",&ncpus, &len, NULL, 0 ) ==0 )
	{
		if ( sysctlbyname ( "kern.smp.maxcpus",&maxcpus, &len, NULL, 0 ) ==0 )
		{
			char b[256];
			len=sizeof(b);
			sysctlbyname("hw.model",&b,&len,NULL,0);
			cpu=b;
			cpu.remove(" ");
			icpu=0;
			lencpu=cpu.length();
			cpuLblHeight=height() *0.5;
			w=cpuLblHeight;
			setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, sizePolicy().hasHeightForWidth() ) );
			setMinimumSize ( QSize ( w*ncpus+cpuLblMargin*2, w+cpuLblMargin*2 ) );
			setMaximumSize ( QSize ( w*ncpus+cpuLblMargin*2, w+cpuLblMargin*2 ) );
			setPaletteBackgroundColor ( QColor ( 128,128,128 ) );
			clockinfo ci;
			len=sizeof ( ci );
			sysctlbyname ( "kern.clockrate",&ci,&len,NULL,0 );
			ccalib= colmax / ( ( float ) ci.stathz/(1000./(double)interval) );// for 500 ms timer
			bgcol=paletteBackgroundColor();
			len_cp_times=maxcpus*CPUSTATES*sizeof ( long );
			cp_times= ( unsigned long* ) malloc ( len_cp_times );
			cp_times_old= ( unsigned long* ) malloc ( len_cp_times );
			showCpuStat=0;
			sysctlbyname ( "kern.cp_times", cp_times_old, &len_cp_times, NULL, 0);
			timer=startTimer ( interval );
		}

	}
#else
	close();
#endif
}

//
void CpuMonitor::timerEvent ( QTimerEvent *e )
{
#if defined(__FreeBSD__) && (__FreeBSD__ >= 7)
	QPainter p ( this );
	QPen p0 ( Qt::SolidLine );
	int rr,gg,bb;
	QBrush b0 ( Qt::SolidPattern );

	if ( ncpus==0 ) return;

	if ( sysctlbyname ( "kern.cp_times", cp_times, &len_cp_times, NULL, 0 ) !=0 ) return;

	if ( showCpuStat>=ncpus ) showCpuStat=- ( ncpus-1-1 );
	for ( int i=0;i<ncpus;i++ )
	{
		int v= ( ( cp_times[i*CPUSTATES]-cp_times_old[i*CPUSTATES] ) *ccalib );
		if ( v>colmax ) v=colmax;
		if ( v<0 ) v=0;
		if ( i==abs ( showCpuStat ) )
		{
			b0.setColor ( bgcol );
			p.fillRect ( i*cpuLblHeight+cpuLblMargin,cpuLblMargin,
			             cpuLblHeight,cpuLblHeight,b0 );

			p.setPen ( qRgb ( 0,255,255 ) );
			QFont f ( "Sans Serif", 8, QFont::Normal );
			p.setFont ( f );
			if(icpu>=lencpu) icpu=0;
			p.drawText ( i*cpuLblHeight+cpuLblMargin+4,cpuLblMargin+11,QString(cpu.at(icpu)) );
			icpu++;
		}
		else
		{
			rr=mypalette[v].r;
			gg=mypalette[v].g;
			bb=mypalette[v].b;
			b0.setColor ( QColor ( rr,gg,bb ) );
			p.fillRect ( i*cpuLblHeight+cpuLblMargin+3,cpuLblMargin+3,
			             cpuLblHeight-6,cpuLblHeight-6,b0 );
			p0.setColor ( QColor ( rr*0.9,gg*0.9,bb*0.9 ) );
			p.setPen ( p0 );
			p.drawRoundRect ( i*cpuLblHeight+cpuLblMargin+2,cpuLblMargin+2,
			                  cpuLblHeight-4,cpuLblHeight-4,25,25 );
			p0.setColor ( QColor ( rr*0.8,gg*0.8,bb*0.8 ) );
			p.setPen ( p0 );
			p.drawRoundRect ( i*cpuLblHeight+cpuLblMargin+1,cpuLblMargin+1,
			                  cpuLblHeight-2,cpuLblHeight-2,25,25 );
			p0.setColor ( QColor ( rr*0.7,gg*0.7,bb*0.7 ) );
			p.setPen ( p0 );
			p.drawRoundRect ( i*cpuLblHeight+cpuLblMargin,cpuLblMargin,
			                  cpuLblHeight,cpuLblHeight,50,50 );
		}
	}
	showCpuStat++;
	memcpy ( cp_times_old, cp_times, len_cp_times );
#endif
}
//
void CpuMonitor::mousePressEvent ( QMouseEvent *e )
{
}
